function [output,counts] = my_getunique(input,nanflag)
%[output, counts] = my_getunique(input) 
%
% 输出含有NaN的数组中数的集合,并返回他们的个数
%   input： 
%   	可以是含有NaN/NaT的二维矩阵或向量,更新三维矩阵也可以。
%   	也可以是字符串数组或者字符元胞数组。
%   output: 
%   	input中所有元素的集合,已排序（若包括NaN/NaT数据，则只出现一次）。
%   	counts： output集合中元素对应的个数。
% 依赖函数:
%   my_shiftdim()
% 作者 Sid（cnqdcyq@163.com）
% 时间：2021年7月4日
% log：
%   ver01：2021年7月1日 【创建】
%   ver02: 2021年7月4日 【功能】能够输出含有NaN的结果
%   ver03: 2021年11月17日 【功能】能够输出含有NaT的结果
%   ver04: 2022年3月22日 【功能】支持字符元胞数组和字符串数组。

arguments
    input
    nanflag {mustBeMember(nanflag,["omitnan","includenan"])} = "includenan"
end
switch ndims(input)
    % input是向量和二维矩阵的时候
    case 2
        if isvector(input)
            [output,counts] = getunique(input(:),nanflag);
        else
            [output, counts] = getunique(input,nanflag);
        end
    % input是三维矩阵的时候，先转成二维矩阵
    case 3
        tmp = my_shiftdim(input,1);
        [output, counts] = getunique(tmp,nanflag);
    otherwise
        error('输入超出3维矩阵，函数不适用')
end
        
    function [Output,Size]=my_shiftdim(Input,Case,Size)
		% [Output, Size] = my_shiftdim(Input, Case, Size)
		% ------ 自定义函数 ------
		% 将三维lat-lon-time数组转化为二维的time-(lon,lat)数组
		% 或进行逆操作。
		%
		% 参数说明：
		%   Input:输入的三维矩阵|或二维矩阵。
		%   Case: 若为1，则三维变二维；若为2，则逆操作，二维变三维。
		%   Output:经过处理后输出的矩阵。
		%   Size: 三维矩阵的数据，逆操作的时候需要用到。
		%
		% 二维数组的坐标如下排布
		%          lon1,lat1 lon1,lat2 lon1,lat3
		% time1
		% time2
		% time3
		%
		% 函数变换的过程演示，见demo_for_my_shiftdim.m

		switch Case
			case 1
				Size = size(Input);
				Output = reshape(shiftdim(Input,2),Size(3),[]);
			case 2
				Output = shiftdim( reshape(Input,Size(3),Size(1),[]),1);
		end
    end
    

    function [output,counts] = getunique(input,nanflag)
        if isdatetime(input)
			% if is datetime
            NaNTag = isnat(input);
            NaNLabel = NaT;
		elseif isstring(input)  
			% if is string
			NaNTag = ismissing(input);
			NaNLabel = NaN;
		elseif iscell(input) && iscellstr(input(~ismissing(string(input))))
			% if is char cell
			NaNTag = ismissing(string(input));
			NaNLabel = NaN;
        else
			% if is matrix
            NaNTag = isnan(input);
            NaNLabel = NaN;
        end

        [output,~,ic] = unique(input(~NaNTag));
        counts = accumarray(ic,1);
        if (nanflag == "includenan") && any(NaNTag,'all')
            output = [output;NaNLabel];
            counts = [counts;numel(input)-sum(counts)];
        end
    end 
end
